﻿using NDK.Module.BLL;
using NDK.Module.Model;
using NDK.Motion.BLL;
using NDK.Motion.MachineManager;
using NDK.Motion.Monitor;
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Threading;

namespace NDK.Module.StationLogic
{
    [Monitor(Description = "PPG工位")]
    public class PPG : StationLogic
    {
        #region 通用
        //记录当前步骤，用于步骤变化的比较
        private StationStep _curStep = StationStep.开始准备;
        //对外提供工位的步骤变化事件
        public override event PropertyChangedEventHandler PropertyChanged;
        //对外提供唯一实例
        public static PPG Instance = new PPG();
        //私有化的构造函数
        private PPG () : base()
        {
            this.Name = "PPG";
        }
        //步骤字段、属性
        private StationStep _step = StationStep.开始准备;
        [Monitor(Description = "当前步骤")]
        public StationStep Step
        {
            get
            {
                return _step;
            }
            set
            {
                if(_curStep != value)
                {
                    _step = value;
                    _curStep = value;

                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
                }
            }
        }
        #endregion

        /// <summary>
        /// 工站初始化
        /// </summary>
        public override void Init ()
        {
            base.Init();
            Step = StationStep.开始准备;
            logBaseInfo = "PPG";
            DataQueue1 = new ConcurrentQueue<MeasureProduct>();
            DataQueue2 = new ConcurrentQueue<MeasureProduct>();
        }

        /// <summary>
        /// 工站动作流程
        /// </summary>
        /// <param name="mode"></param>
        public override void ActionProcess ()
        {
            try
            {
                switch(Step)
                {
                    case StationStep.开始准备:
                        Step = StationStep.流程开始;
                        break;
                    case StationStep.流程开始:
                        if(Common.isWriteLog)
                        {
                            logCtStr = string.Empty;
                            swStepTime.Restart();
                            swStationCT.Restart();
                            logCtStr += $"{logBaseInfo},PPG工站开始,{swStepTime.ElapsedMilliseconds},{Environment.NewLine}";
                        }
                        Step = StationStep.轴初始位;
                        break;

                    case StationStep.轴初始位:
                        if(MotionControl.AxesMove(Machine.pos_PPG_初始位))
                        {
                            工位要料 = true;
                            Step = StationStep.等待上工站完成;
                        }
                        break;

                    case StationStep.等待上工站完成:
                        if(LoadingTrans1.Instance.工位完成)
                        {
                            工位要料 = false;
                            Common.sw6.Restart();
                            Step = StationStep.克隆数据;
                        }
                        break;

                    case StationStep.克隆数据:
                        Step = StationStep.轴测量位;
                        break;

                    case StationStep.轴测量位:
                        if(MotionControl.AxesMove(Machine.pos_PPG_测量位))
                        {
                            Step = StationStep.PPG测量;
                        }
                        break;

                    case StationStep.PPG测量:
                        Thread.Sleep(Common.PPG保压时间);
                        var value1 = Common.启用PPG ? Machine.PPG1.Read("01") + Common.PPGOffset1 : 999;
                        var value2 = Common.启用PPG ? Machine.PPG2.Read("01") + Common.PPGOffset2 : 999;
                        if(!Common.屏蔽治具1)
                        {
                            MeasureProduct md = new MeasureProduct();
                            md.MeasureData.Add(new DataItem()
                            {
                                ID = 0,
                                Name = Common.PPG_Name,
                                Value = value1
                            });
                            DataQueue1.Enqueue(md);
                        }
                        if(!Common.屏蔽治具2)
                        {
                            MeasureProduct md = new MeasureProduct();
                            md.MeasureData.Add(new DataItem()
                            {
                                ID = 0,
                                Name = Common.PPG_Name,
                                Value = value2
                            });
                            DataQueue2.Enqueue(md);
                        }
                        Step = StationStep.轴过渡位;
                        break;
                    case StationStep.轴过渡位:
                        if(MotionControl.AxesMove(Machine.pos_PPG_过渡位))
                        {
                            Step = StationStep.轴回原位;
                        }
                        break;

                    case StationStep.轴回原位:
                        if(MotionControl.AxesMove(Machine.pos_PPG_初始位))
                        {
                            Step = StationStep.等待下工位开要料;
                        }
                        break;

                    case StationStep.等待下工位开要料:
                        if(LoadingTrans2.Instance.工位要料)
                        {
                            工位完成 = true;
                            Step = StationStep.等待下工位关要料;
                        }
                        break;

                    case StationStep.等待下工位关要料:
                        if(!LoadingTrans2.Instance.工位要料)
                        {
                            工位完成 = false;
                            Step = StationStep.判断模式;
                        }
                        break;

                    case StationStep.判断模式:
                        if((!Common.GRR循环模式 || Common.GRREnd) && !Common.pointCheck)
                        {
                            Step = StationStep.流程结束;
                        }
                        else
                        {
                            GRR工位要料 = true;
                            Step = StationStep.GRR等待下工位完成;
                        }
                        break;

                    case StationStep.GRR等待下工位完成:
                        if(LoadingTrans2.Instance.GRR工位完成)
                        {
                            GRR工位要料 = false;
                            GRR工位完成 = true;
                            Step = StationStep.GRR等待上工位关要料;
                        }
                        break;

                    case StationStep.GRR等待上工位关要料:
                        if(!LoadingTrans1.Instance.GRR工位要料)
                        {
                            GRR工位完成 = false;
                            Step = StationStep.流程结束;
                        }
                        break;

                    case StationStep.流程结束:
                        Common.sw6.Stop();
                        if(Common.isWriteLog)
                        {
                            logCtStr += $"{logBaseInfo},PPG结束,{swStepTime.ElapsedMilliseconds},{Environment.NewLine}";
                            logCtStr += $"{logBaseInfo},PPG结束,{swStationCT.ElapsedMilliseconds},{Environment.NewLine}";
                            PublicMethod.WriteLogToTxt(logCtStr, $"000StepCT_{DateTime.Now.ToString("yyyyMMdd")}", "6.PPG");
                        }
                        Step = StationStep.开始准备;
                        break;

                }
            }
            catch(Exception ex)
            {
                UILog_Error($"[PPG ActionProcess Thread ERROR] {ex.Message}");
            }
        }

        public override void EmptyActionProcess ()
        {
            ActionProcess();
        }

        public override void GRRActionProcess ()
        {
            ActionProcess();
        }

        /// <summary>
        /// 工位步骤定义
        /// </summary>
        public enum StationStep
        {
            开始准备,
            流程开始,
            轴初始位,
            允许放料,
            等待上工站完成,
            克隆数据,
            轴测量位,
            PPG测量,
            轴过渡位,
            轴回原位,
            工站完成,
            等待下工位开要料,
            等待下工位关要料,
            判断模式,
            GRR允许放料,
            GRR等待下工位完成,
            GRR等待上工位关要料,
            GRR等待取料,
            流程结束,
        }
    }
}